package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.protocol.Common.PBRankMember;
import com.motu.monstercity.protocol.CsGameSystem;
import com.motu.monstercity.protocol.CsGameSystem.CSGameSystemRedPointResponse;
import com.motu.monstercity.server.game.commondata.rank.RankConstant;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.redis.RedisTools;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import io.vertx.core.Future;
import io.vertx.core.json.JsonArray;

import java.util.ArrayList;
import java.util.List;

public class RankManager extends RankUserData {
    //全量更新排行
    public static void updateRank(int rankType, int serverId, long userId, long score, String dateKey) {
        String rankName = getRankName(rankType, serverId, dateKey);
        double updateScore = getTimeScore(rankType, score, TimeUtils.getCurTime());// 用分数+时间戳组合来更新榜单,默认是当前时间
        RedisTools.addRank(rankName, userId, updateScore);
    }

    /**
     * 删除排行榜
     */
    public static void removeFromRank(int rankType, int serverId, long id, String dateKey) {
        String rankName = getRankName(rankType, serverId, dateKey);
        RedisTools.removeFromRank( rankName, id);
    }

    // 获取我的排名
    public static int getMyRank(int rankType, int serverId, long userId, String dateKey) {
        String rankName = getRankName(rankType, serverId, dateKey);
        Long result = Future.await(RedisTools.getMyRank(rankName, userId + ""));
        return result.intValue();
    }

    //获取我的分数
    public static long getMyScore(int rankType, int serverId, long userId, String dateKey) {
        String rankName = getRankName(rankType, serverId, dateKey);
        double result = Future.await(RedisTools.getMyScore(rankName, userId));
        if (result < 0) {
            return 0L;
        }
        return getTrueScore(result);
    }

    public static long getRankLength(int rankType, int serverId, String dateKey) {
        String rankName = getRankName(rankType, serverId, dateKey);
        return Future.await(RedisTools.getRankLen(rankName));
    }


    /**
     * 读取榜单成员列表
     *
     * @param rankType
     * @param serverId
     * @param dateKey
     * @param num      长度100个,还是200
     * @return
     */
    public static List<PBRankMember.Builder> getRankMemberList(int rankType, int serverId, String dateKey, int num) {
        List<PBRankMember.Builder> result = new ArrayList<PBRankMember.Builder>();

        String rankName = getRankName(rankType, serverId, dateKey);
        boolean withScore = true;// 带分数返回的是[id1,score1,id2,score2]）
        JsonArray list = Future.await(RedisTools.getRankListByIndex(rankName, 0, num - 1, withScore));
        JsonArray uidArray = new JsonArray();// userid 列表
        for (int i = 0; i < list.size(); i++) {// userid,分数,userid,分数
            if (i % 2 == 0) {// userid
                uidArray.add(list.getString(i));
            }
        }
        for (int i = 0; i < list.size(); i++) {
            if (i % 2 == 0) {// userid
                String uidStr = list.getString(i);
                long uid = Long.parseLong(uidStr);// 用户id
                double score = getTrueScore(Double.parseDouble(list.getString(i + 1)));// 根据时间计算的积分
                if (score > 0) {// 负数和0不下发
                    PBRankMember.Builder rankMember = PBRankMember.newBuilder();
                    rankMember.setUserId(uid);
                    rankMember.setScore((long) score);
                    if (rankType == RankConstant.ACTIVITY_CROSS_RANK_UNION_SCUFFLE || rankType == RankConstant.SERVER_UNION_RANK_MOBILE) {
                        UnionInfo unionInfo = UnionManager.getUnionInfo(uid);
                        if (unionInfo != null) {
                            rankMember.setUnionName(unionInfo.getName());
                            rankMember.setUnionLevel(unionInfo.getLevel());
                            rankMember.setUnionIcon(unionInfo.getIcon());
                        }
                    } else {
                        UserShow userShow = GameUser.getUserShow(uid);
                        rankMember.setUserShow(userShow.takeInitBuilder());
                        if (rankType == RankConstant.ACTIVITY_CROSS_RANK_UNION_SCUFFLE_SINGLE) {
                            UserUnion userUnion = UnionManager.getUserUnion(uid);
                            if (userUnion.getUnionId() > 0) {
                                UnionInfo unionInfo = UnionManager.getUnionInfo(userUnion.getUnionId());
                                if (unionInfo != null) {
                                    rankMember.setUnionName(unionInfo.getName());
                                    rankMember.setUnionLevel(unionInfo.getLevel());
                                    rankMember.setUnionIcon(unionInfo.getIcon());
                                }
                            }
                        }
                    }

                    result.add(rankMember);
                }
            }
        }
        return result;
    }

    public static JsonArray getRankIdListByIndex(int rankType, int serverId, String dateKey,int startIndex,int endIndex) {
        String rankName = getRankName(rankType, serverId, dateKey);
        JsonArray list = Future.await(RedisTools.getRankListByIndex(rankName, startIndex, endIndex - 1, true));
        JsonArray uidArray = new JsonArray();// userid 列表
        for (int i = 0; i < list.size(); i++) {// userid,分数,userid,分数
            if (i % 2 == 0) {// userid
                uidArray.add(list.getString(i));
            }
        }
        return uidArray;
    }

    /**
     * 榜单的名字redis 的key rank.t1001.s1001.0
     * @param rankType
     * @param serverId
     * @param values 榜单有周期性的一般传datekey.如一周一个榜。固定的榜单一般不传
     * @return
     */
    public static String getRankName(int rankType, int serverId, Object... values) {
        String rankName = "rank.t" + rankType + ".s" + serverId;
        if (values.length == 0) {
            rankName += ".0";// 没传datekey
        } else {
            for (int i = 0; i < values.length; i++) {
                if (values[i] == null || "".equals(values[i])) {
                    continue;
                }
                rankName += "." + values[i];
            }
        }
        return rankName;
    }

    // 上榜分数是否需要加时间戳type<2000 按score+time 排序
    private static boolean isTimeScore(int rankType) {
        if (rankType < RankConstant.RANK_TIME_SCORE_RANGE) {
            return true;
        } else {
            return false;
        }
    }

    // 根据榜单类型,返回datekey: 20250421
    public static String getDateKey(int rankType) {
        long dateTime = 0L;
        switch (rankType) {
            case RankConstant.SERVER_RANK_SNATCH:
                dateTime = TimeUtils.getWeekOneTime(1, 0);// 这周一的0点0分0秒的时间戳
                break;
            case RankConstant.SERVER_RANK_WORLD_BOSS,RankConstant.SERVER_UNION_RANK_WORLD_BOSS:
                dateTime = TimeUtils.getStartTimeOfDay(TimeUtils.getCurTime());// 今日的0点0分0秒的时间戳
                break;
            default:
                break;
        }
        if (dateTime > 0) {
            return TimeUtils.getDayStr(dateTime);
        } else {
            return "0";
        }
    }

    /**
     * 获得复合分数(积分+时间的组合排序) 整数部分是实际的分数，小数点是时间加权，越早的加权越大，排在前面
     * @param score 真实积分（不能超过922337203，9亿2千万）
     */
    public static double getTimeScore(int rankType, long score, long timeStamp) {
        if (score >= Integer.MAX_VALUE || !isTimeScore(rankType)) {
            return score;
        }
        double add = 1 - (double) timeStamp / 9999999999L;
        return score + add;
    }

    public static double getTimeScore(long score, long timeStamp) {
        if (score >= Integer.MAX_VALUE) {
            return score;
        }
        double add = 1 - (double) timeStamp / 9999999999L;
        return score + add;
    }

    /**
     * 根据计算积分获取真实积分. 整数部分是实际的分数，小数点是时间加权，越早的加权越大，排在前面
     * @param countScore 计算积分（真实积分和时间计算出来的值）
     */
    public static long getTrueScore(double countScore) {
        double result = Math.floor(countScore);
        return (long) result;
    }

    // 膜拜红点
    public static boolean checkRedPointWorship(CSGameSystemRedPointResponse.Builder builder, UserInfo userInfo){
        JsonArray reward = new JsonArray();// 有膜拜奖励的榜单
        reward.add(RankConstant.SERVER_RANK_SECR);// 秘书亲密值
        reward.add(RankConstant.SERVER_RANK_POWER);// 战力排行榜
        reward.add(RankConstant.SERVER_RANK_EARN);// 城市收益

        UserAffair userAffair = GameUser.getUserAffair(userInfo.getId());
        JsonArray jsonArray = userAffair.getWorshipArray();// 今日膜拜过的榜单
        if (jsonArray.size() < reward.size()) {
            CsGameSystem.RedPoint_Worship.Builder redPoint = CsGameSystem.RedPoint_Worship.newBuilder();
            redPoint.setWorship(true);
            builder.setWorship(redPoint);
            return true;
        } else {
            return false;
        }
    }
}
